{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "### pry-docの読み込み\n",
    "require \"/root/git_jupyter_notebook/Ruby/vendor/bundle/ruby/2.3.0/gems/pry-doc-0.10.0/lib/pry-doc\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Arrayクラス\n",
    "\n",
    "配列は Arrayクラスのオブジェクト"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Array, JSON::Ext::Generator::GeneratorMethods::Array, Enumerable, Object, PP::ObjectMixin, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject]"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Array.ancestors"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の生成\n",
    "\n",
    "* 生成方法\n",
    "    * 配列式\n",
    "    * Arrayクラスのクラスメソッド\n",
    "        * []メソッド\n",
    "        * newメソッド\n",
    "            * 配列の長さと初期値を指定\n",
    "            * 配列を指定\n",
    "            * ブロックで配列の長さを渡す"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[]メソッド\n",
      "[1, 2, 3]\n",
      "[4, 5, 6]\n",
      "newメソッド引数指定(配列の長さと初期値)\n",
      "[\"hoge\", \"hoge\", \"hoge\"]\n",
      "newメソッド引数指定(配列)\n",
      "[7, 8, 9]\n",
      "newメソッド引数指定(ブロック)\n",
      "[\"fugafuga\", \"fugafuga\", \"fugafuga\"]\n",
      "[1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "puts \"[]メソッド\"\n",
    "puts a = [1, 2, 3]\n",
    "puts b = Array[4, 5, 6]\n",
    "puts \"newメソッド引数指定(配列の長さと初期値)\"\n",
    "puts c = Array.new(3, \"hoge\")\n",
    "puts \"newメソッド引数指定(配列)\"\n",
    "puts d = Array.new([7, 8, 9])\n",
    "puts \"newメソッド引数指定(ブロック)\"\n",
    "puts d = Array.new(3){|a|  \"fuga\" * 2}\n",
    "puts d = Array.new(3){|a|  1+ a}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列に要素を追加\n",
    "\n",
    "* メソッド\n",
    "    * `<<`\n",
    "        * 指定された引数にあるオブジェクトを自分自身の末尾に追加\n",
    "    * push\n",
    "        * 指定された引数にあるオブジェクトを自分自身の末尾に追加\n",
    "    * concat\n",
    "        * 指定された配列を自分自身の末尾に連結\n",
    "    * insert\n",
    "        * 1番目の引数で指定された場所にそれ以降で指定されたオブジェクトを挿入する\n",
    "    * +\n",
    "        * 自分自身と引数で与えられた配列を連結した配列を<font color=\"red\">新たに生成して返す</font>\n",
    "    * unshift\n",
    "        * 指定されたオブジェクトを配列の先頭に追加する\n",
    "    * <font color=\"red\">+以外は破壊的メソッド</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3]\n",
      "[1, 2, 3, 4]\n",
      "[1, 2, 3, 4, 5]\n",
      "[1, 2, 3, 4, 5, 6, 7]\n",
      "[1, 2, 3, \"a\", \"b\", \"c\", 4, 5, 6, 7]\n",
      "[1, 2, 3, \"a\", \"b\", \"c\", 4, 5, 6, 7, 8, 9]\n",
      "[1, 2, 3, \"a\", \"b\", \"c\", 4, 5, 6, 7]\n",
      "[0, 1, 2, 3, \"a\", \"b\", \"c\", 4, 5, 6, 7]\n"
     ]
    }
   ],
   "source": [
    "puts a = [1, 2, 3]\n",
    "puts a << 4\n",
    "puts a.push(5)\n",
    "puts a.concat([6, 7])\n",
    "puts a.insert(3, \"a\", \"b\", \"c\")\n",
    "puts a + [8, 9]\n",
    "puts a\n",
    "puts a.unshift(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の要素を変更する\n",
    "\n",
    "* メソッド\n",
    "    * []=\n",
    "        * 指定したインデックスにある要素を書き換える\n",
    "            * 整数\n",
    "            * Rangeオブジェクト\n",
    "            * 始点と終点指定\n",
    "    * fill\n",
    "        * 配列のすべての要素を指定したオブジェクトに変更する\n",
    "        * 引数を取る場合は配列の視点と終点を指定できる\n",
    "            * Rangeオブジェクトでも指定できる\n",
    "            * ブロックを取ることもできる\n",
    "    * replace\n",
    "        * 引数で指定した配列で自分自身を置き換える\n",
    "        * =での再代入と異なり、<font color=\"red\">オブジェクトIDは変化しない</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5]\n",
      "[1, 6, 3, 4, 5]\n",
      "[1, 7, 4, 5]\n",
      "[1, 7, 4, 5, nil, nil, nil, nil, 8]\n",
      "\n",
      "すべてをAにする\n",
      "[\"A\", \"A\", \"A\", \"A\", \"A\", \"A\", \"A\", \"A\", \"A\"]\n",
      "index2以降をBにする\n",
      "[\"A\", \"A\", \"B\", \"B\", \"B\", \"B\", \"B\", \"B\", \"B\"]\n",
      "index4から2つをCにする\n",
      "[\"A\", \"A\", \"B\", \"B\", \"C\", \"C\", \"B\", \"B\", \"B\"]\n",
      "index1から7をDにする\n",
      "[\"A\", \"D\", \"D\", \"D\", \"D\", \"D\", \"D\", \"D\", \"B\"]\n",
      "index3から6をEにする(ブロック利用)\n",
      "[\"A\", \"D\", \"D\", \"E\", \"E\", \"E\", \"E\", \"D\", \"B\"]\n",
      "index4から5にindexの値をそのまま入れる(ブロック利用)\n",
      "[\"A\", \"D\", \"D\", \"E\", 4, 5, \"E\", \"D\", \"B\"]\n",
      "\n",
      "replace\n",
      "[1, 2, 3]\n",
      "70031345256040\n",
      "[4, 5, 6]\n",
      "=の再代入はオブジェクトIDが変わる\n",
      "70031345251560\n",
      "[7, 8, 9]\n",
      "replaceはオブジェクトIDは変わらない\n",
      "70031345251560\n"
     ]
    }
   ],
   "source": [
    "puts a = [1, 2, 3, 4, 5]\n",
    "a[1] = 6\n",
    "puts a\n",
    "a[1..2] = 7\n",
    "puts a\n",
    "a[8] = 8\n",
    "puts a\n",
    "puts \"\"\n",
    "\n",
    "puts \"すべてをAにする\"\n",
    "puts a.fill(\"A\")\n",
    "puts \"index2以降をBにする\"\n",
    "puts a.fill(\"B\", 2)\n",
    "puts \"index4から2つをCにする\"\n",
    "puts a.fill(\"C\", 4, 2)\n",
    "puts \"index1から7をDにする\"\n",
    "puts a.fill(\"D\", 1..7)\n",
    "puts \"index3から6をEにする(ブロック利用)\"\n",
    "puts a.fill(3..6){|s| \"E\"}\n",
    "puts \"index4から5にindexの値をそのまま入れる(ブロック利用)\"\n",
    "puts a.fill(4..5){|s2| s2}\n",
    "puts \"\"\n",
    "\n",
    "puts \"replace\"\n",
    "puts b = [1, 2, 3]\n",
    "puts b.object_id\n",
    "b = [4, 5, 6]\n",
    "puts b\n",
    "puts \"=の再代入はオブジェクトIDが変わる\"\n",
    "puts b.object_id\n",
    "puts b.replace([7, 8, 9])\n",
    "puts \"replaceはオブジェクトIDは変わらない\"\n",
    "puts b.object_id"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の要素を参照する\n",
    "\n",
    "* []\n",
    "    * 整数、Rangeオブジェクト、始点と終点の指定\n",
    "* slice\n",
    "    * []と同じ\n",
    "* values_at\n",
    "    * 要素が一つの場合でも<font color=\"red\">結果を配列で返す</font>\n",
    "    * <font color=\"red\">挙動が[],sliceとvalues_atで違う</font>\n",
    "        * a.slice(2,3)\n",
    "            * index2を含めて右方向に3個要素を配列で返す\n",
    "        * a.values_at(2,3)\n",
    "            * index2,3の2個の要素を配列で返す\n",
    "        * a.values_at(2,4,6)\n",
    "            * index2,4,6の3個の要素を配列で返す\n",
    "* at\n",
    "    * indexが整数の時に利用可能\n",
    "    * 要素数よりも多い値を入れるとnilを返す\n",
    "* fetch\n",
    "    * 基本的にatと同じ\n",
    "    * 要素数よりも多い値を入れるとIndexErrorとなる\n",
    "        * 第二引数が指定されていると、範囲外の場合はその値を返す\n",
    "        * ブロックがあるとその評価結果を返す\n",
    "* first\n",
    "    * 配列の先頭の要素を返す\n",
    "    * 引数で指定した数だけ返す\n",
    "* last\n",
    "    * 配列の末尾の要素を返す\n",
    "    * 引数で指定した数だけ返す\n",
    "* assoc\n",
    "    * 配列の配列を検索し、配列の最初の要素が指定した値と==で等しければその要素を返す\n",
    "        * 複数ある場合は最初の要素のみ\n",
    "        * 配列でないものは検索対象外\n",
    "    * 無ければnilを返す\n",
    "* rassoc\n",
    "    * 配列の配列を検索し、配列のindex1の要素が指定した値と==で等しければその要素を返す\n",
    "        * 複数ある場合は最初の要素のみ\n",
    "        * 配列でないものは検索対象外\n",
    "    * 無ければnilを返す\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6]\n",
      "4\n",
      "5\n",
      "[3, 4, 5]\n",
      "[2, 3, 4]\n",
      "\n",
      "slice\n",
      "4\n",
      "5\n",
      "[3, 4, 5]\n",
      "[2, 3, 4]\n",
      "\n",
      "values_at\n",
      "[4]\n",
      "[5]\n",
      "[3, 4]\n",
      "[3, 4, 5]\n",
      "[2, 3, 4]\n",
      "\n",
      "at\n",
      "4\n",
      "5\n",
      "nil\n",
      "\n",
      "fetch\n",
      "4\n",
      "5\n",
      "範囲外のindexが指定されていると第二引数の値を返す\n",
      "-1\n",
      "範囲外のindexが指定されているとブロックの評価結果を返す\n",
      "ERROR : 範囲外ですよ。。\n",
      "\n",
      "first, last\n",
      "1\n",
      "[1, 2, 3]\n",
      "6\n",
      "[4, 5, 6]\n",
      "\n",
      "assoc, rassoc\n",
      "[1, \"1\", [1, 2, 3], [4, 5, 6], [6, \"5\", 4]]\n",
      "配列の最初の要素が1の[1,2,3]が返る。整数の1や文字列の1は無視される\n",
      "[1, 2, 3]\n",
      "配列のindex1要素が5の[4,5,6]が返る\n",
      "[4, 5, 6]\n",
      "配列のindex1要素が\"5\"の[6,\"5\",4]が返る\n",
      "[6, \"5\", 4]\n"
     ]
    }
   ],
   "source": [
    "puts a = [1, 2, 3, 4, 5, 6]\n",
    "puts a[3]\n",
    "puts a[-2]\n",
    "puts a[2,3]\n",
    "puts a[1..3]\n",
    "puts \"\"\n",
    "\n",
    "puts \"slice\"\n",
    "puts a.slice(3)\n",
    "puts a.slice(-2)\n",
    "puts a.slice(2,3)\n",
    "puts a.slice(1..3)\n",
    "puts \"\"\n",
    "\n",
    "puts \"values_at\"\n",
    "puts a.values_at(3)\n",
    "puts a.values_at(-2)\n",
    "puts a.values_at(2,3)\n",
    "puts a.values_at(2,3,4)\n",
    "puts a.values_at(1..3)\n",
    "puts \"\"\n",
    "\n",
    "puts \"at\"\n",
    "puts a.at(3)\n",
    "puts a.at(-2)\n",
    "p a.at(10)\n",
    "### エラーになる\n",
    "#puts a.at(2,3)\n",
    "#puts a.at(1..3)\n",
    "puts \"\"\n",
    "\n",
    "puts \"fetch\"\n",
    "puts a.fetch(3)\n",
    "puts a.fetch(-2)\n",
    "### エラーになる\n",
    "#p a.fetch(10)\n",
    "#puts a.fetch(1..3)\n",
    "puts \"範囲外のindexが指定されていると第二引数の値を返す\"\n",
    "puts a.fetch(10,-1)\n",
    "puts \"範囲外のindexが指定されているとブロックの評価結果を返す\"\n",
    "puts a.fetch(10){|n| \"ERROR : 範囲外ですよ。。\"}\n",
    "puts \"\"\n",
    "\n",
    "puts \"first, last\"\n",
    "puts a.first\n",
    "puts a.first(3)\n",
    "puts a.last\n",
    "puts a.last(3)\n",
    "puts \"\"\n",
    "\n",
    "puts \"assoc, rassoc\"\n",
    "puts a = [1, \"1\", [1,2,3],[4,5,6],[6,\"5\",4]]\n",
    "puts \"配列の最初の要素が1の[1,2,3]が返る。整数の1や文字列の1は無視される\"\n",
    "puts a.assoc(1)\n",
    "puts \"配列のindex1要素が5の[4,5,6]が返る\"\n",
    "puts a.rassoc(5)\n",
    "puts '配列のindex1要素が\"5\"の[6,\"5\",4]が返る'\n",
    "puts a.rassoc(\"5\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の要素を調べる\n",
    "\n",
    "* メソッド\n",
    "    * include?\n",
    "        * 指定された値が要素の中に存在していると真を返す\n",
    "    * index\n",
    "        * 配列の先頭から指定された値と==で等しい位置の要素を返す\n",
    "        * 見つからない場合はnilを返す\n",
    "        * ブロックも使える\n",
    "    * rindex\n",
    "        * 配列の末尾から指定された値と==で等しい位置の要素を返す\n",
    "        * 見つからない場合はnilを返す\n",
    "        * ブロックも使える"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\"a\", \"b\", \"c\", \"c\", \"c\", \"d\", \"e\"]\n",
      "false\n",
      "2\n",
      "4\n",
      "2\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "puts a = [\"a\", \"b\", \"c\", \"c\", \"c\", \"d\", \"e\"]\n",
    "puts a.include?(c)\n",
    "puts a.index(\"c\")\n",
    "puts a.rindex(\"c\")\n",
    "puts a.index {|s| s == \"c\"}\n",
    "puts a.rindex {|s| s == \"c\"}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の要素を削除する\n",
    "\n",
    "* メソッド\n",
    "    * delete_at\n",
    "        * 指定したindexに対応する要素を取り除いてその<font color=\"red\">要素を返す</font>\n",
    "    * delete_if\n",
    "        * 要素にブロックを渡し、その評価結果が真になった要素を全て取り除いた<font color=\"red\">自分自身を返す</font>\n",
    "    * reject!\n",
    "        * delete_ifと同じ\n",
    "    * delete\n",
    "        * 指定された値と == メソッドで等しい要素があれば取り除いてその<font color=\"red\">要素を返す</font>\n",
    "    * slice!\n",
    "        * 指定されたインデックスに対応する要素を取り除き、その<font color=\"red\">要素を返す</font>\n",
    "        * 整数、Rangeオブジェクト、始点長さを指定できる\n",
    "    * shift\n",
    "        * 先頭から指定された数だけ要素を取り除く\n",
    "        * デフォルトは1\n",
    "    * pop\n",
    "        * 末尾から指定された数だけ要素を取り除く\n",
    "        * デフォルトは1\n",
    "    * -\n",
    "        * 指定された配列にある要素を自分自身から取り除いた配列を返す\n",
    "        * <font color=\"red\">元の配列は変化なし</font>\n",
    "    * clear\n",
    "        * 要素をすべて消す\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\"hoge0\", \"hoge1\", \"hoge2\", \"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\"]\n",
      "\n",
      "deleted_at\n",
      "hoge2\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\"]\n",
      "nil\n",
      "\n",
      "deleted_if\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\"]\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge6\", \"hoge7\", \"hoge8\"]\n",
      "\n",
      "reject!\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge6\", \"hoge7\", \"hoge8\"]\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge6\", \"hoge7\"]\n",
      "\n",
      "delete\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge6\", \"hoge7\"]\n",
      "hoge7\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge6\"]\n",
      "\n",
      "slice!\n",
      "[\"hoge0\", \"hoge1\", \"hoge3\", \"hoge4\", \"hoge6\"]\n",
      "hoge1\n",
      "[\"hoge0\", \"hoge3\", \"hoge4\", \"hoge6\"]\n",
      "[\"hoge3\", \"hoge4\"]\n",
      "[\"hoge0\", \"hoge6\"]\n",
      "[\"hoge0\", \"hoge6\"]\n",
      "[]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "puts a = Array.new(9){|s| \"hoge#{s}\"}\n",
    "puts \"\"\n",
    "\n",
    "puts \"deleted_at\"\n",
    "puts a.delete_at(2)\n",
    "puts a\n",
    "p a.delete_at(20)\n",
    "puts \"\"\n",
    "\n",
    "puts \"deleted_if\"\n",
    "puts a\n",
    "puts a.delete_if{|s| s == \"hoge5\" }\n",
    "puts \"\"\n",
    "\n",
    "puts \"reject!\"\n",
    "puts a\n",
    "puts a.reject!{|s| s == \"hoge8\" }\n",
    "puts \"\"\n",
    "\n",
    "puts \"delete\"\n",
    "puts a\n",
    "puts a.delete(\"hoge7\")\n",
    "puts a\n",
    "puts \"\"\n",
    "\n",
    "puts \"slice!\"\n",
    "puts a\n",
    "puts a.slice!(1)\n",
    "puts a\n",
    "puts a.slice!(1..2)\n",
    "puts a\n",
    "puts a.slice!(0,2)\n",
    "puts a\n",
    "puts \"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 191,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\"hoge0\", \"hoge1\", \"hoge2\", \"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\", \"hoge9\"]\n",
      "\n",
      "shift\n",
      "[\"hoge0\", \"hoge1\", \"hoge2\", \"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\", \"hoge9\"]\n",
      "hoge0\n",
      "[\"hoge1\", \"hoge2\", \"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\", \"hoge9\"]\n",
      "[\"hoge1\", \"hoge2\"]\n",
      "[\"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\", \"hoge9\"]\n",
      "\n",
      "pop\n",
      "[\"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\", \"hoge9\"]\n",
      "hoge9\n",
      "[\"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\", \"hoge7\", \"hoge8\"]\n",
      "[\"hoge7\", \"hoge8\"]\n",
      "[\"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\"]\n",
      "\n",
      "-\n",
      "[\"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\"]\n",
      "[\"hoge3\", \"hoge6\"]\n",
      "[\"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\"]\n",
      "\n",
      "clear\n",
      "[\"hoge3\", \"hoge4\", \"hoge5\", \"hoge6\"]\n",
      "[]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "puts a = Array.new(10){|s| \"hoge#{s}\"}\n",
    "puts \"\"\n",
    "\n",
    "puts \"shift\"\n",
    "puts a\n",
    "puts a.shift\n",
    "puts a\n",
    "puts a.shift(2)\n",
    "puts a\n",
    "puts \"\"\n",
    "\n",
    "puts \"pop\"\n",
    "puts a\n",
    "puts a.pop\n",
    "puts a\n",
    "puts a.pop(2)\n",
    "puts a\n",
    "puts \"\"\n",
    "\n",
    "puts \"-\"\n",
    "puts a\n",
    "puts a - [\"hoge4\", \"hoge5\"]\n",
    "puts a\n",
    "puts \"\"\n",
    "\n",
    "puts \"clear\"\n",
    "puts a\n",
    "puts a.clear\n",
    "puts \"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の演算\n",
    "\n",
    "* 配列を集合とみなした演算ができる\n",
    "    * |\n",
    "        * 和集合\n",
    "    * &\n",
    "        * 積集合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 6]\n",
      "[2]\n"
     ]
    }
   ],
   "source": [
    "puts [1, 2, 3] | [2, 4, 6]\n",
    "puts [1, 2, 3] & [2, 4, 6]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の比較\n",
    "\n",
    "* メソッド\n",
    "    * ==\n",
    "        * 先頭から要素を比較し、全て等しければtrueを返す\n",
    "    * <=>\n",
    "        * 左が大きい : 1\n",
    "        * 同じ : 0\n",
    "        * 右が大きい : -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 199,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==\n",
      "false\n",
      "true\n",
      "\n",
      "<=>\n",
      "-1\n",
      "0\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "b = [2, 4, 6]\n",
    "c = [1, 2, 3]\n",
    "d = [0, 1, 2]\n",
    "\n",
    "puts \"==\"\n",
    "puts a == b\n",
    "puts a == c\n",
    "puts \"\"\n",
    "\n",
    "puts \"<=>\"\n",
    "puts a <=> b\n",
    "puts a <=> c\n",
    "puts a <=> d\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の要素での繰り返し\n",
    "\n",
    "* each\n",
    "    * 配列の要素が渡る\n",
    "* each_index\n",
    "    * 配列のindexが渡る\n",
    "* each_with_index\n",
    "    * 配列の要素とindexが渡る\n",
    "* reverse_each\n",
    "    * 配列の要素を逆順に繰り返す\n",
    "* cycle\n",
    "    * 配列の要素を順に繰り返し、末尾まできたら先頭に戻って繰り返し続ける"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 209,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\"hoge0\", \"hoge1\", \"hoge2\", \"hoge3\"]\n",
      "\n",
      "each\n",
      "hoge0\n",
      "hoge1\n",
      "hoge2\n",
      "hoge3\n",
      "\n",
      "each_index\n",
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "\n",
      "each_with_index\n",
      "0: hoge0\n",
      "1: hoge1\n",
      "2: hoge2\n",
      "3: hoge3\n",
      "\n",
      "reverse_each\n",
      "hoge3\n",
      "hoge2\n",
      "hoge1\n",
      "hoge0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "puts a = Array.new(4){|s| \"hoge#{s}\"}\n",
    "puts \"\"\n",
    "\n",
    "puts \"each\"\n",
    "a.each {|e| puts e}\n",
    "puts \"\"\n",
    "\n",
    "puts \"each_index\"\n",
    "a.each_index {|i| puts i}\n",
    "puts \"\"\n",
    "\n",
    "puts \"each_with_index\"\n",
    "a.each_with_index {|e,i| puts \"#{i}: #{e}\"}\n",
    "puts \"\"\n",
    "\n",
    "puts \"reverse_each\"\n",
    "a.reverse_each {|e| puts e}\n",
    "puts \"\"\n",
    "\n",
    "### 止められないのでコメントアウト\n",
    "# puts \"cycle\"\n",
    "# a.cycle {|e| puts e}\n",
    "# puts \"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の要素を連結する"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 221,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n",
      "123\n",
      "1%2%3\n",
      "1hoge2hoge3\n",
      "\n"
     ]
    }
   ],
   "source": [
    "a = [1, 2, 3]\n",
    "puts a.join\n",
    "puts a.join($,)\n",
    "puts a.join(\"%\")\n",
    "puts a.join(\"hoge\")\n",
    "puts \"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の長さを求める"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 233,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7\n",
      "7\n",
      "0\n",
      "true\n",
      "false\n"
     ]
    }
   ],
   "source": [
    "a = [1, 2, 3, nil, nil, 4, nil]\n",
    "puts a.length\n",
    "puts a.size\n",
    "puts [].size\n",
    "puts [].empty?\n",
    "puts a.empty?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列をsortする\n",
    "\n",
    "* メソッド\n",
    "    * sort\n",
    "        * 配列をソートする\n",
    "        * ブロックが与えられた場合は2つの要素が渡されて結果に応じてソートされる\n",
    "        * sort!で自分自身をsortの結果で書き換える"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 240,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 6, 2, 8, 5, 9, 1, 7, 4]\n",
      "[1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
      "[1, 2, 3, 4, 5, 6, 7, 8, 9]\n",
      "[9, 8, 7, 6, 5, 4, 3, 2, 1]\n",
      "[1, 2, 3, 4, 5, 6, 7, 8, 9]\n"
     ]
    }
   ],
   "source": [
    "puts a = [3, 6, 2, 8, 5, 9, 1, 7, 4]\n",
    "puts a.sort\n",
    "puts a.sort{|a,b| a <=> b}\n",
    "puts a.sort{|a,b| b <=> a}\n",
    "\n",
    "a.sort!\n",
    "puts a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列を変換する\n",
    "\n",
    "* メソッド\n",
    "    * uniq\n",
    "        * 配列から重複した要素を取り除いた配列を返す\n",
    "    * compact\n",
    "        * 要素のnilを取り除いた配列を返す\n",
    "    * reverse\n",
    "        * 配列の要素を逆順に並べ替えた配列を返す\n",
    "    * flatten\n",
    "        * 配列を再帰的に平滑化した配列を返す。引数が指定されるとその深さまで再帰的に行う\n",
    "    * collect\n",
    "        * 要素ごとにブロックを評価し、その結果で要素を置き換えた配列を返す\n",
    "    * map\n",
    "        * collectと同じ\n",
    "    * shuffle\n",
    "        * 配列の要素をシャッフルして返す\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 260,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3]\n",
      "[1, 2, 3]\n",
      "[3, 2, 1]\n",
      "\n",
      "flatten\n",
      "[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]\n",
      "[1, 2, 3, 4, 5, 6, 7, 8]\n",
      "[[1, 2], [3, 4], [5, 6], [7, 8]]\n",
      "[1, 2, 3, 4, 5, 6, 7, 8]\n",
      "\n",
      "[2, 4, 6]\n",
      "[nil, 4, nil]\n",
      "\n",
      "[9, 5, 8, 6, 3, 1, 7, 4, 2]\n"
     ]
    }
   ],
   "source": [
    "puts [1, 2, 2, 3, 3, 3].uniq\n",
    "puts [1, nil, nil, 2, nil, 3].compact\n",
    "puts [1, 2, 3].reverse\n",
    "puts \"\"\n",
    "\n",
    "puts \"flatten\"\n",
    "puts [[[1,2],[3,4]],[[5,6],[7,8]]]\n",
    "puts [[[1,2],[3,4]],[[5,6],[7,8]]].flatten\n",
    "puts [[[1,2],[3,4]],[[5,6],[7,8]]].flatten(1)\n",
    "puts [[[1,2],[3,4]],[[5,6],[7,8]]].flatten(2)\n",
    "puts \"\"\n",
    "\n",
    "puts [1,2,3].map{|i| i * 2 }\n",
    "puts [1,2,3].collect{|i| i * 2 if i == 2}\n",
    "puts \"\"\n",
    "\n",
    "puts [1,2,3,4,5,6,7,8,9].shuffle"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列の組み合わせを生成する\n",
    "\n",
    "* メソッド\n",
    "    * product\n",
    "        * 自身と与えられた配列から1つずつ要素を取って組み合わせた配列をつくり、そのすべての組み合わせを要素とする配列を返す\n",
    "    * zip\n",
    "        * 自身と与えられた配列から1つずつ要素を取って配列をつくり、それを要素とする配列を返す\n",
    "        * 組み合わせは前から順に同じインデックスのもののみとなる\n",
    "    * transpose\n",
    "        * 配列の配列を行と列からなるデータと見立てて、行と列を入れ替えた配列の配列を作成して返す\n",
    "    * *\n",
    "        * 与えられた数値の分だけ繰り返した配列を返す\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true,
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1, \"a\"], [1, \"b\"], [2, \"a\"], [2, \"b\"], [3, \"a\"], [3, \"b\"]]\n",
      "[[1, \"a\", \"x\"], [1, \"b\", \"x\"], [2, \"a\", \"x\"], [2, \"b\", \"x\"], [3, \"a\", \"x\"], [3, \"b\", \"x\"]]\n",
      "[[1, \"a\"], [2, \"b\"], [3, nil]]\n",
      "[[1, \"a\", \"x\"], [2, \"b\", nil], [3, nil, nil]]\n",
      "\n",
      "[[1, 4], [2, 5], [3, 6]]\n",
      "\n",
      "[1, 2, 1, 2, 1, 2]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "puts [1,2,3].product([\"a\",\"b\"])\n",
    "puts [1,2,3].product([\"a\",\"b\"],[\"x\"])\n",
    "puts [1,2,3].zip([\"a\",\"b\"])\n",
    "puts [1,2,3].zip([\"a\",\"b\"],[\"x\"])\n",
    "puts\n",
    "puts [[1, 2, 3],\n",
    "      [4, 5, 6]].transpose\n",
    "puts\n",
    "puts [1,2] * 3\n",
    "puts\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 配列をパックする\n",
    "\n",
    "packメソッドは、自身を指定されたテンプレートに従ってパックする"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 270,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"44Or44OT44O8\\n\""
      ]
     },
     "execution_count": 270,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[\"ルビー\"].pack(\"m\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Ruby 2.3.1",
   "language": "ruby",
   "name": "ruby"
  },
  "language_info": {
   "file_extension": ".rb",
   "mimetype": "application/x-ruby",
   "name": "ruby",
   "version": "2.3.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
